import { PostModel } from '/@/api/system/model/postModel'
import { arrayRemoveByPropertyValue } from '/@/utils/twUtils'
/*
 * @Description: 用户信息
 * @Author: DHL
 * @Date: 2022-04-02 14:02:17
 * @LastEditors: DHL
 * @LastEditTime: 2022-11-01 10:01:37
 */

import { defineComponent, computed, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { cloneDeep, assign } from 'lodash-es'
import { UserModel } from '/@/api/system/model/userModel'
import { apiUserGetById, apiUserSave, apiUserUpdateById, searchUsersList } from '/@/api/system/user'
import { RoleModel } from '/@/api/system/model/roleModel'
import { apiRoleSearchList } from '/@/api/system/role'
import { log } from '/@/utils/log'
import { apiOrganizationSearchTree } from '/@/api/system/organization'
import { arrayFilter, arrayLastValue, getTreeParentName, listToTree } from '/@/utils/twUtils'
import { OrganizationModel } from '/@/api/system/model/organizationModel'
import { isEmpty } from '/@/utils/isUtils'
import { apiPostSearchList } from '/@/api/system/post'

export default defineComponent({
  name: 'UserForm',
  emits: ['refreshTableData'],
  setup(props, { emit, expose }) {
    //////////////////////////////////////////////////
    // 属性
    //////////////////////////////////////////////////
    const dbFormRef = ref()
    const loading = ref(true)

    /**
     * 表单操作标记
     */
    const action = ref('add')

    /**
     * 显示弹框
     */
    const visible = ref(false)

    /**
     * 标题
     */
    const title = computed(() => {
      let rtn = ''
      switch (action.value) {
        case 'add':
          rtn = '新增'
          break
        case 'edit':
          rtn = '编辑'
          break
        default:
          rtn = '查看'
          break
      }
      return rtn
    })

    /**
     * 公共
     */
    const state = reactive({
      orgId: '',
      orgName: '',
      activeName: 'basic'
    })

    //////////////////////////////////////////////////
    // 表单
    //////////////////////////////////////////////////

    const defaultForm = {
      id: '', // 编号
      tenantId: '', // 租户ID
      platformId: '', // 平台ID
      loginName: '', // 登陆名称
      pwd: '', // 登录密码
      name: '', // 姓名
      userType: '', // 用户类型
      phone: '', // 手机号码
      mail: '', // 邮箱
      status: '1', // 用户状态（0，失效；1，生效）
      firstLogin: '1', // 是否第一次登录（0，否；1，是）
      openid: '', // 微信OPENID
      photo: '', // 头像
      clientId: '', // APP客户端唯一标识
      position: '', // 职务
      cpUserId: '', // 企业微信用户ID
      roles: [], // 角色
      posts: [], // 岗位
      directSupervisor: '' // 直属主管
    }

    let dbForm = reactive<UserModel>(cloneDeep(defaultForm))

    //////////////////////////////////////////////////
    // 表单验证规则
    //////////////////////////////////////////////////

    /**
     * 表单验证规则
     */
    const rules = reactive({
      orgId: [
        {
          required: true,
          message: '请选择机构',
          trigger: 'blur'
        }
      ],
      loginName: [
        {
          required: true,
          message: '请输入登陆名称',
          trigger: 'blur'
        },
        {
          max: 100,
          message: '最多可输入100个字符',
          trigger: 'blur'
        }
      ],
      pwd: [
        {
          required: true,
          message: '请输入登录密码',
          trigger: 'blur'
        },
        {
          max: 100,
          message: '最多可输入100个字符',
          trigger: 'blur'
        }
      ],
      name: [
        {
          required: true,
          message: '请输入姓名',
          trigger: 'blur'
        },
        {
          max: 100,
          message: '最多可输入100个字符',
          trigger: 'blur'
        }
      ],
      userType: [
        {
          required: true,
          message: '请输入用户类型',
          trigger: 'blur'
        },
        {
          max: 10,
          message: '最多可输入10个字符',
          trigger: 'blur'
        }
      ],
      position: [
        {
          required: false,
          message: '请输入职务',
          trigger: 'blur'
        },
        {
          max: 10,
          message: '最多可输入10个字符',
          trigger: 'blur'
        }
      ],
      phone: [
        {
          required: false,
          message: '请输入手机号码',
          trigger: 'blur'
        },
        {
          max: 11,
          message: '最多可输入11个字符',
          trigger: 'blur'
        }
      ],
      mail: [
        {
          required: false,
          message: '请输入邮箱',
          trigger: 'blur'
        },
        {
          max: 50,
          message: '最多可输入50个字符',
          trigger: 'blur'
        }
      ],
      status: [
        {
          required: true,
          message: '请选择用户状态',
          trigger: 'blur'
        },
        {
          max: 10,
          message: '最多可输入10个字符',
          trigger: 'blur'
        }
      ],
      photo: [
        {
          required: false,
          message: '请输入头像',
          trigger: 'blur'
        },
        {
          max: 500,
          message: '最多可输入500个字符',
          trigger: 'blur'
        }
      ],
      clientId: [
        {
          required: false,
          message: '请输入APP客户端唯一标识',
          trigger: 'blur'
        },
        {
          max: 100,
          message: '最多可输入100个字符',
          trigger: 'blur'
        }
      ]
    })

    //////////////////////////////////////////////////
    // 函数
    //////////////////////////////////////////////////

    /**
     * 打开弹框
     */
    function handleOpen(
      actionParam: string,
      rowParam?: UserModel,
      orgParams?: { orgId: string; orgName: string }
    ) {
      visible.value = true
      loading.value = false
      action.value = actionParam

      handleSearchPost()
      handleSerachDirectSupervisor()

      // 角色
      const roleAdd = {
        orgId: '',
        orgName: '',
        roleId: '',
        roleName: '',
        action: 'add'
      }

      // 岗位
      const postAdd = {
        orgId: '',
        orgName: '',
        postId: '',
        postName: '',
        action: 'add'
      }

      handleSearchOrgTree().then(() => {
        if (['edit', 'view'].indexOf(actionParam) > -1 && rowParam) {
          loading.value = true
          apiUserGetById(rowParam.id)
            .then((result) => {
              if (result?.success && result?.data) {
                assign(state, {
                  orgId: result.data.orgId,
                  orgName: result.data.orgParentNames
                })

                assign(dbForm, result.data)

                // 角色
                dbForm.roles = [roleAdd]
                if (result.data.roles) {
                  result.data.roles.forEach((item) => {
                    dbForm.roles.push(
                      assign(item, {
                        action: 'delete',
                        orgName: getTreeParentName(orgListData, 'id', 'parentOrgId', 'name', {
                          id: item.orgId
                        }).join(' / ')
                      })
                    )
                  })
                }

                // 岗位
                dbForm.posts = [postAdd]
                if (result.data.posts) {
                  result.data.posts.forEach((item) => {
                    dbForm.posts.push(
                      assign(item, {
                        action: 'delete',
                        orgName: getTreeParentName(orgListData, 'id', 'parentOrgId', 'name', {
                          id: item.orgId
                        }).join(' / ')
                      })
                    )
                  })
                }
              }
            })
            .finally(() => {
              loading.value = false
            })
        } else {
          assign(state, orgParams)
          assign(dbForm, orgParams)
          // 角色
          dbForm.roles = [roleAdd]
          // 岗位
          dbForm.posts = [postAdd]
        }
      })
    }

    /**
     * 关闭弹框
     */
    function handleClose() {
      assign(dbForm, cloneDeep(defaultForm))
      visible.value = false
    }

    /**
     * 提交表单
     */
    function handleSubmit(isContinue: boolean) {
      dbFormRef.value.validate((valid: boolean) => {
        if (valid) {
          if (action.value === 'add') {
            addFun(isContinue)
          } else {
            editFun()
          }
        } else {
          log.warn('用户管理', '表单校验失败')
        }
      })
    }

    /**
     * 新增
     * @param isContinue 是否新增并继续
     */
    function addFun(isContinue: boolean) {
      const submitParams = cloneDeep(dbForm)
      arrayRemoveByPropertyValue(submitParams.roles, 'action', 'add')
      arrayRemoveByPropertyValue(submitParams.posts, 'action', 'add')

      loading.value = true

      apiUserSave(submitParams)
        .then((result) => {
          if (result?.success) {
            handleReset(!isContinue)
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 编辑
     * @returns
     */
    function editFun() {
      const submitParams = cloneDeep(dbForm)
      arrayRemoveByPropertyValue(submitParams.roles, 'action', 'add')
      arrayRemoveByPropertyValue(submitParams.posts, 'action', 'add')

      loading.value = true

      apiUserUpdateById(submitParams)
        .then((result) => {
          if (result?.success) {
            handleReset(true)
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 重置表单
     * @param isClosed 是否关闭弹框
     */
    function handleReset(isClosed: boolean) {
      assign(dbForm, cloneDeep(defaultForm))
      if (isClosed) {
        emit('refreshTableData')
        visible.value = false
      }
    }

    //////////////////////////////////////////////////
    // 机构
    //////////////////////////////////////////////////
    const orgTreeData = ref()
    let orgListData: Array<OrganizationModel> = []

    /**
     * 查询机构数据
     */
    function handleSearchOrgTree() {
      return new Promise<void>((resolve, reject) => {
        apiOrganizationSearchTree()
          .then((result) => {
            if (result?.success) {
              orgListData = result.data
              orgTreeData.value = listToTree(
                result?.data ? result.data : [],
                'id',
                'parentOrgId',
                ''
              )
            }
          })
          .finally(() => {
            resolve()
          })
      })
    }

    /**
     * 机构改变事件
     * @param value
     */
    function handleChangeOrg(value: Array<string>) {
      dbForm.orgId = arrayLastValue(value)

      dbFormRef.value.validateField('orgId')
    }

    //////////////////////////////////////////////////
    // 角色
    //////////////////////////////////////////////////
    const roleList = ref([] as Array<RoleModel>)

    /**
     * 角色机构改变事件
     * @param value
     */
    function handleChangeRoleOrg(value: Array<string>) {
      const orgId = arrayLastValue(value)
      handleSearchRoleByOrgId(orgId)
    }

    /**
     * 根据机构ID查询角色列表
     */
    function handleSearchRoleByOrgId(orgId: string) {
      apiRoleSearchList({
        orgId: orgId
      }).then((result) => {
        if (result?.success && result?.data) {
          roleList.value = result?.data
        }
      })
    }

    /**
     * 增加角色
     */
    function handleAddRole(row) {
      if (isEmpty(row.orgId) || isEmpty(row.roleId)) {
        ElMessage.warning('请选择角色')
        return
      }

      const role = cloneDeep(row)

      const orgName = getTreeParentName(orgListData, 'id', 'parentOrgId', 'name', {
        id: arrayLastValue(role.orgId)
      })
      const roleObj = arrayFilter<RoleModel>(roleList.value, 'id', role.roleId)[0]

      assign(role, {
        action: 'delete',
        orgId: arrayLastValue(role.orgId),
        orgName: orgName.join(' / '),
        roleName: roleObj.name
      })

      dbForm.roles.push(role)
    }

    /**
     * 删除角色
     * @param row
     */
    function handleDeleteRole(row) {
      for (let i = dbForm.roles.length - 1; i >= 0; i--) {
        const role = dbForm.roles[i]
        if (role.roleId == row.roleId && role.action === 'delete') {
          dbForm.roles.splice(i, 1)
        }
      }
    }

    //////////////////////////////////////////////////
    // 岗位
    //////////////////////////////////////////////////

    const postList = ref([] as Array<PostModel>)

    /**
     * 查询岗位下拉列表
     */
    function handleSearchPost() {
      apiPostSearchList({}).then((result) => {
        if (result?.success && result?.data) {
          postList.value = result?.data
        }
      })
    }

    /**
     * 增加岗位
     */
    function handleAddPost(row) {
      if (isEmpty(row.orgId) || isEmpty(row.postId)) {
        ElMessage.warning('请选择岗位')
        return
      }

      const post = cloneDeep(row)

      const orgName = getTreeParentName(orgListData, 'id', 'parentOrgId', 'name', {
        id: arrayLastValue(post.orgId)
      })
      const postObj = arrayFilter<RoleModel>(postList.value, 'id', post.postId)[0]

      assign(post, {
        action: 'delete',
        orgId: arrayLastValue(post.orgId),
        orgName: orgName.join(' / '),
        postName: postObj.name
      })

      dbForm.posts.push(post)
    }

    /**
     * 删除角色
     * @param row
     */
    function handleDeletePost(row) {
      for (let i = dbForm.posts.length - 1; i >= 0; i--) {
        const post = dbForm.posts[i]
        if (post.postId == row.postId && post.action === 'delete') {
          dbForm.posts.splice(i, 1)
        }
      }
    }

    //////////////////////////////////////////////////
    // 直属领导
    //////////////////////////////////////////////////
    const directSupervisorList = ref([] as Array<{ label: string; value: UserModel }>)

    /**
     * 查询直属领导下拉
     */
    function handleSerachDirectSupervisor() {
      directSupervisorList.value = []
      searchUsersList({}).then((result) => {
        if (result?.success) {
          result.data.forEach((item) => {
            directSupervisorList.value.push({
              label: item.name,
              value: item
            })
          })
        }
      })
    }

    //////////////////////////////////////////////////
    // 生命周期
    //////////////////////////////////////////////////

    /**
     * 暴露函数
     */
    expose({ handleOpen })

    return {
      loading,
      visible,
      action,
      title,
      state,
      dbFormRef,
      dbForm,
      rules,
      handleOpen,
      handleClose,
      handleSubmit,
      handleReset,
      roleList,
      orgTreeData,
      handleChangeOrg,
      handleChangeRoleOrg,
      handleAddRole,
      handleDeleteRole,
      postList,
      handleAddPost,
      handleDeletePost,
      directSupervisorList
    }
  }
})
